package org.xnat.xnatfs.webdav;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

import org.apache.log4j.Logger;
import org.xnat.xnatfs.asset.IStreamAsset;
import org.xnat.xnatfs.exception.RequestException;

import com.bradmcevoy.http.Range;
import com.bradmcevoy.http.exceptions.NotAuthorizedException;

public class RemoteFile extends VirtualFile {
  private static final Logger logger = Logger.getLogger ( RemoteFile.class );

  private String mURL;
  private long contentLength;

  public RemoteFile ( XNATFS x, String path, String name, String url, long length ) {
    super ( x, path, name );
    if ( url == null ) {
      // TODO is this path ever actually hit? the 1 call to this constructor
      // always passes a url
      mURL = path + name;
    } else {
      mURL = url;
    }
    contentLength = length;
    logger.debug ( "RemoteFile constructor absolute path is: " + absolutePath );
  }

  @Override
  public Long getContentLength () {
    if ( contentLength == 0 ) {
      try {
        contentLength = retreiveAssetHead ().getContentLength ();
      } catch ( RequestException e ) {
        return null;
      }
    }
    return new Long ( contentLength );
  }

  @Override
  public void sendContent ( OutputStream out, Range range, Map<String, String> params, String contentType ) throws IOException, NotAuthorizedException {
    // TODO add support for Range (implement by only requesting that range from
    // the REST API)
    // TODO consider inserting optional ability to cache file locally
    IStreamAsset asset = null;
    InputStream is = null;
    try {
      asset = (IStreamAsset) retreiveAsset ();
      is = asset.getContent ();
      // Skip if requested
      if ( range != null ) {
        is.skip ( range.getStart () );
      }
      int b;
      byte buffer[] = new byte[4096];
      while ( ( b = is.read ( buffer ) ) != -1 ) {
        out.write ( buffer, 0, b );
      }
    } catch ( RequestException e ) {
      throw new IOException ( e );
    } finally {
      close ();
      // flush to the client
      // No longer any need to flush the client, this happens in the library.
      // out.flush ();
    }
  }

  @Override
  protected String getRestUrl () {
    return mURL;
  }

  @Override
  protected IStreamAsset requestAsset ( String url ) throws RequestException {
    return xnatfs.getAssetProvider ().getStreamAsset ( url, getAuth () );
  }

}
